package testBase;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

import java.util.HashSet;
import java.util.List;
import java.util.Random;

import objects.User;
import objects.UserSet;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

import pages.Page;
import pages.UserManagmentPage;

public class UserBase extends TestBase {
	
	private Random rnd = new Random();
	
	private UserSet usersModel;
	protected boolean usersModelRebuild;
	
	public void testUIAndDBUserListConformsModel() {			
		UserSet modelList = getUIUsers();
		UserSet uiList = getUIUsers();
		assertThat(uiList,equalTo(modelList));
	}

	public void prepare(int i) {
		logInByAdmin();
		synchronizeUsers();
		prepareUsers(i);
	}
	
	public User createUser(User user) {
		Page.clickUserManagement();
		Page.createRandomUser(user);
		return user;
	
	}	
	
	public void userModifacation(User user) {
		User newUser = app.getUserDataGenerator().generateRandomEmailAndRole();
		Page.clickUserManagement();
		Page.userModify(user, newUser);
		usersModel = usersModel.without(user).withAdded(newUser);		
	}
	

	public void prepareUsers(int i) {
		while (getUsers().size() < i) {
			User user = app.getUserDataGenerator().generateRandomUser();
			
			createUser(user);
		}
	}
	
	public void synchronizeUsers() {
		usersModelRebuild = true;
		getUsers();
		usersModelRebuild = false;
	}
	
	public UserSet getUsers() {
			usersModel = getUIUsers();
	return usersModel;
	}
	
	public UserSet getUIUsers() {
		HashSet<User> set = new HashSet<User>();
		Page.clickUserManagement();
		
		List<WebElement> entries = findUsers();
		for (WebElement entry : entries) {
			User user = getUserDetails(entry);
			set.add(user);
		} 
		UserSet users = new UserSet(set);
		return users;
	}
	
	private List<WebElement> findUsers() {
		wait.until(visibilityOfElementLocated(By.tagName("table")));
		WebElement tbody = UserManagmentPage.userTable.findElement(By.tagName("tbody"));
		List<WebElement> entries = tbody.findElements(By.tagName("tr"));
		
		return entries;
	}
	
	private User getUserDetails(WebElement entry) {
		WebElement td = entry.findElements(By.tagName("td")).get(0);
		String href = td.findElement(By.tagName("a")).getAttribute("href");
		String id = href.replace("http://localhost/php4dvd/?go=user&id=", "");
		String name = entry.findElements(By.tagName("td")).get(1).getText();
		String email = entry.findElements(By.tagName("td")).get(2).getText();
		String role = entry.findElements(By.tagName("td")).get(3).getText();
		
		User user = new User()
							.setName(name)
								.setEmail(email)
									.setId(id)
										.setRole(role);
		return user;
	}
	
	public void createRandomUser() {
		User user = app.getUserDataGenerator().generateRandomUser();
		createUser(user);
		usersModel = usersModel.withAdded(user);
	}
	
	public void removeRandomUser() {
		User user = app.getUserDataGenerator().generateRandomUser();
		userRemove(user);
		usersModel = usersModel.without(user);
	}
	
	public User userRemove(User user) {
		WebElement tr = UserManagmentPage.userTable.findElement(By.xpath("//a[@href='./?go=user&id=" + user.getId() + "']/../.."));
		tr.findElement(By.cssSelector("img[src='http://localhost/php4dvd/tpl/default/images/icons/16x16/delete.png']")).click();
		wait.until(alertIsPresent()).accept();
		return user;
	}

	public User getRandomRemovableUser() {
		User user;
		do {
			user = getRandomUser();
		} while (user.getName().equals("admin"));
		return user;
	 }

	public User getRandomUser() {
		return (User) getSetElement(getUsers().getStoredUsers(), rnd.nextInt(getUsers().size())); 
	}

}
